home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1994-09-22 | 3.7 KB | 158 lines |
- IMPLEMENTATION MODULE HashTable;
-
- (*
- * This module implements a hash table with strings as keys.
- * It could easily be modified to have additional elements.
- *
- * Usage assumptions:
- * The calling module MUST have created a heap before calling these routines!!
- *
- * Copyright 1987, Barry Locklear
- *
- * The author grants the privilege of distributing this
- * software free, or for a nominal charge to cover the media
- * costs, or for connect time.
- *
- * Distribution for commercial gain is prohibited.
- *
- * The only exception is that Jefferson Software may
- * distribute it with their Modula-2 package if they so
- * desire.
- *
- * If improvements are made, please send them to me.
- * Compuserve: 76327,2102
- * Genie: BLOCKLEAR
- * The Jefferson Software BBS (602)276-6102
- *
- * This MODULE is written in Jefferson Software Modula-2
- *)
-
- FROM Heap IMPORT ALLOCATE, DEALLOCATE;
- FROM String IMPORT Assign, Compare, GetTerminator, Equal;
- FROM SYSTEM IMPORT TSIZE;
-
- IMPORT Terminal;
-
- CONST
- HASHTABLESIZE = 29; (* number of hash table buckets *)
-
- TYPE
- EntryPtr = POINTER TO HashEntry;
-
- HashEntry = RECORD
- HashEntry : ARRAY [0..14] OF CHAR;
- HashVal : CARDINAL;
- NextEntry : EntryPtr;
- END;
-
- VAR
- HashTableArray : ARRAY [0..HASHTABLESIZE-1] OF EntryPtr;
- index : INTEGER;
-
- (* --------------------------------------------------------------------*)
-
- (*
- * Calculates a hash value using the very simple method of adding
- * the values of the characters in the string.
- *)
- PROCEDURE CalcHashVal( Str : ARRAY OF CHAR ) : CARDINAL;
- VAR
- index : INTEGER;
- hashVal : CARDINAL;
- stringTerm : CHAR;
-
- BEGIN
- hashVal := 0;
- index := 0;
- stringTerm := GetTerminator();
-
- LOOP
- IF (index > HIGH(Str)) OR (Str[ index ] = stringTerm)
- THEN EXIT;
- END; (* IF *)
-
- (* ORD is supposed to return a CARDINAL value!!!! *)
- (* see page 162 of the third ed. of Wirth's book *)
- hashVal := hashVal + VAL( CARDINAL, ORD(Str[index]));
- INC( index );
- END; (* LOOP *)
-
- RETURN hashVal;
- END CalcHashVal;
-
- (* --------------------------------------------------------------------*)
-
- (*
- * Inserts an element into the hash table
- *)
- PROCEDURE InsertElem( Elem : ARRAY OF CHAR );
-
- VAR
- newEntryPtr : EntryPtr;
-
- hashIndex,
- hashVal : CARDINAL;
-
- BEGIN
- hashVal := CalcHashVal( Elem );
- hashIndex := hashVal MOD HASHTABLESIZE;
-
- (*
- * allocate the entry and fill it up
- *)
- ALLOCATE( newEntryPtr, TSIZE( HashEntry ));
-
- IF newEntryPtr = NIL THEN
- Terminal.WriteString("ModPrint: Out of Memory!"); Terminal.WriteLn;
- RETURN;
- END; (* IF *)
-
- Assign( newEntryPtr^.HashEntry, Elem );
-
- newEntryPtr^.HashVal := hashVal;
-
- (*
- * Now insert the new entry into the table
- *)
- newEntryPtr^.NextEntry := HashTableArray[ hashIndex ];
- HashTableArray[ hashIndex ] := newEntryPtr;
-
- END InsertElem;
-
- (* --------------------------------------------------------------------*)
-
- (*
- * Lookup an entry in the table to see if it is there
- *)
- PROCEDURE LookupElem( Entry : ARRAY OF CHAR ) : BOOLEAN;
-
- VAR
- hashVal,
- hashIndex : CARDINAL;
- walkPtr : EntryPtr;
-
- BEGIN
- hashVal := CalcHashVal( Entry );
- hashIndex := hashVal MOD HASHTABLESIZE;
- walkPtr := HashTableArray[ hashIndex ];
-
- WHILE walkPtr <> NIL DO
- IF hashVal = walkPtr^.HashVal THEN
- IF Compare( Entry, walkPtr^.HashEntry ) = Equal THEN
- RETURN TRUE;
- END; (* IF *)
- END; (* IF *)
- walkPtr := walkPtr^.NextEntry;
- END; (* WHILE *)
-
- RETURN FALSE;
-
- END LookupElem;
-
- BEGIN
- (* Make certain that the table is NIL *)
- FOR index := 0 TO HASHTABLESIZE-1 DO
- HashTableArray[ index ] := NIL;
- END; (* FOR *)
- END HashTable.
-